package plugin

import (
	"context"
	"fmt"
	"sync"
)

// PluginType 插件类型
type PluginType string

const (
	// PluginTypeProcessor 处理器插件
	PluginTypeProcessor PluginType = "processor"
	// PluginTypeConnector 连接器插件
	PluginTypeConnector PluginType = "connector"
	// PluginTypeMonitor 监控插件
	PluginTypeMonitor PluginType = "monitor"
	// PluginTypeWASM WebAssembly 插件
	PluginTypeWASM PluginType = "wasm"
	// PluginTypeRPC RPC 插件
	PluginTypeRPC PluginType = "rpc"
	// PluginTypeGo Go 插件
	PluginTypeGo PluginType = "go"
	// PluginTypeProcess 外部进程插件
	PluginTypeProcess PluginType = "process"
)

// PluginStatus 插件状态
type PluginStatus string

const (
	// StatusCreated 已创建
	StatusCreated PluginStatus = "created"
	// StatusInitialized 已初始化
	StatusInitialized PluginStatus = "initialized"
	// StatusRunning 运行中
	StatusRunning PluginStatus = "running"
	// StatusPaused 已暂停
	StatusPaused PluginStatus = "paused"
	// StatusStopped 已停止
	StatusStopped PluginStatus = "stopped"
	// StatusError 错误状态
	StatusError PluginStatus = "error"
)

// PluginInfo 包含插件的基本信息
type PluginInfo struct {
	ID          string                 `json:"id"`
	Name        string                 `json:"name"`
	Type        PluginType             `json:"type"`
	Mode        PluginMode             `json:"mode"`
	Version     string                 `json:"version"`
	APIVersion  int                    `json:"api_version"`
	Author      string                 `json:"author"`
	Description string                 `json:"description"`
	License     string                 `json:"license"`
	Homepage    string                 `json:"homepage"`
	Config      map[string]interface{} `json:"config"`
}

// PluginConfig 插件配置
type PluginConfig struct {
	// ID 插件ID
	ID string `json:"id"`
	// Name 插件名称
	Name string `json:"name"`
	// Description 插件描述
	Description string `json:"description"`
	// Type 插件类型
	Type PluginType `json:"type"`
	// Version 插件版本
	Version string `json:"version"`
	// Path 插件路径
	Path string `json:"path"`
	// Config 插件配置
	Config map[string]interface{} `json:"config"`
	// Enabled 是否启用
	Enabled bool `json:"enabled"`
}

// Plugin 插件接口
type Plugin interface {
	// ID 返回插件ID
	ID() string

	// Name 返回插件名称
	Name() string

	// Description 返回插件描述
	Description() string

	// Type 返回插件类型
	Type() PluginType

	// Version 返回插件版本
	Version() string

	// Status 返回插件状态
	Status() PluginStatus

	// Config 返回插件配置
	Config() *PluginConfig

	// Init 初始化插件
	Init(ctx context.Context, config *PluginConfig) error

	// Start 启动插件
	Start(ctx context.Context) error

	// Stop 停止插件
	Stop(ctx context.Context) error

	// Pause 暂停插件
	Pause(ctx context.Context) error

	// Resume 恢复插件
	Resume(ctx context.Context) error

	// Validate 验证插件配置
	Validate(config *PluginConfig) error
}

// PluginExecutor 插件执行器接口
type PluginExecutor interface {
	// Execute 执行插件
	Execute(ctx context.Context, input []byte) ([]byte, error)

	// ExecuteWithContext 执行插件，带上下文
	ExecuteWithContext(ctx context.Context, functionName string, input []byte) ([]byte, error)
}

// PluginLifecycle 插件生命周期接口
type PluginLifecycle interface {
	// Load 加载插件
	Load(ctx context.Context) error

	// Unload 卸载插件
	Unload(ctx context.Context) error

	// Reload 重新加载插件
	Reload(ctx context.Context) error
}

// PluginMetadata 插件元数据接口
type PluginMetadata interface {
	// GetName 获取插件名称
	GetName() string

	// GetVersion 获取插件版本
	GetVersion() string

	// GetAuthor 获取插件作者
	GetAuthor() string

	// GetDescription 获取插件描述
	GetDescription() string

	// GetFeatures 获取插件功能
	GetFeatures() []string

	// GetDependencies 获取插件依赖
	GetDependencies() []string
}

// PluginManager 插件管理器接口
type PluginManager interface {
	// RegisterPlugin 注册插件
	RegisterPlugin(plugin Plugin) error

	// UnregisterPlugin 注销插件
	UnregisterPlugin(id string) error

	// GetPlugin 获取插件
	GetPlugin(id string) (Plugin, error)

	// ListPlugins 列出所有插件
	ListPlugins() []Plugin

	// ListPluginsByType 列出指定类型的插件
	ListPluginsByType(pluginType PluginType) []Plugin

	// StartPlugin 启动插件
	StartPlugin(id string) error

	// StopPlugin 停止插件
	StopPlugin(id string) error

	// LoadPlugin 加载插件
	LoadPlugin(ctx context.Context, config *PluginConfig) (Plugin, error)
}

// PluginLoader 插件加载器接口
type PluginLoader interface {
	// Load 加载插件
	Load(ctx context.Context, config *PluginConfig) (Plugin, error)

	// GetSupportedType 获取支持的插件类型
	GetSupportedType() PluginType
}

// PluginRepo 插件仓库接口
type PluginRepo interface {
	// ListPlugins 列出所有插件
	ListPlugins(ctx context.Context) ([]PluginMetadata, error)

	// GetPlugin 获取插件
	GetPlugin(ctx context.Context, name, version string) ([]byte, error)

	// PublishPlugin 发布插件
	PublishPlugin(ctx context.Context, plugin []byte, metadata PluginMetadata) error

	// RemovePlugin 删除插件
	RemovePlugin(ctx context.Context, name, version string) error
}

// Manager 插件管理器实现
type Manager struct {
	mu      sync.RWMutex
	plugins map[string]Plugin
	configs map[string]*PluginConfig
	loaders map[PluginType]PluginLoader
}

// NewManager 创建新的插件管理器
func NewManager() *Manager {
	return &Manager{
		plugins: make(map[string]Plugin),
		configs: make(map[string]*PluginConfig),
		loaders: make(map[PluginType]PluginLoader),
	}
}

// RegisterPlugin 注册插件
func (m *Manager) RegisterPlugin(plugin Plugin) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	id := plugin.ID()
	if _, exists := m.plugins[id]; exists {
		return fmt.Errorf("plugin with ID %s already registered", id)
	}

	m.plugins[id] = plugin
	m.configs[id] = &PluginConfig{
		ID:          plugin.ID(),
		Type:        plugin.Type(),
		Version:     plugin.Version(),
		Description: plugin.Description(),
		Config:      make(map[string]interface{}),
		Enabled:     false,
	}

	return nil
}

// UnregisterPlugin 注销插件
func (m *Manager) UnregisterPlugin(id string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if _, exists := m.plugins[id]; !exists {
		return fmt.Errorf("plugin with ID %s not found", id)
	}

	delete(m.plugins, id)
	delete(m.configs, id)

	return nil
}

// GetPlugin 获取插件
func (m *Manager) GetPlugin(id string) (Plugin, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	plugin, exists := m.plugins[id]
	if !exists {
		return nil, fmt.Errorf("plugin with ID %s not found", id)
	}

	return plugin, nil
}

// ListPlugins 列出所有插件
func (m *Manager) ListPlugins() []Plugin {
	m.mu.RLock()
	defer m.mu.RUnlock()

	plugins := make([]Plugin, 0, len(m.plugins))
	for _, plugin := range m.plugins {
		plugins = append(plugins, plugin)
	}

	return plugins
}

// ListPluginsByType 列出指定类型的插件
func (m *Manager) ListPluginsByType(pluginType PluginType) []Plugin {
	m.mu.RLock()
	defer m.mu.RUnlock()

	var result []Plugin
	for _, plugin := range m.plugins {
		if plugin.Type() == pluginType {
			result = append(result, plugin)
		}
	}

	return result
}

// StartPlugin 启动插件
func (m *Manager) StartPlugin(id string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	plugin, exists := m.plugins[id]
	if !exists {
		return fmt.Errorf("plugin with ID %s not found", id)
	}

	ctx := context.Background()
	if err := plugin.Init(ctx, m.configs[id]); err != nil {
		return fmt.Errorf("failed to initialize plugin %s: %w", id, err)
	}

	if err := plugin.Start(ctx); err != nil {
		return fmt.Errorf("failed to start plugin %s: %w", id, err)
	}

	m.configs[id].Enabled = true

	return nil
}

// StopPlugin 停止插件
func (m *Manager) StopPlugin(id string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	plugin, exists := m.plugins[id]
	if !exists {
		return fmt.Errorf("plugin with ID %s not found", id)
	}

	if !m.configs[id].Enabled {
		return nil
	}

	ctx := context.Background()
	if err := plugin.Stop(ctx); err != nil {
		return fmt.Errorf("failed to stop plugin %s: %w", id, err)
	}

	m.configs[id].Enabled = false

	return nil
}

// RegisterLoader 注册插件加载器
func (m *Manager) RegisterLoader(loader PluginLoader) {
	m.mu.Lock()
	defer m.mu.Unlock()

	m.loaders[loader.GetSupportedType()] = loader
}

// LoadPlugin 加载插件
func (m *Manager) LoadPlugin(ctx context.Context, config *PluginConfig) (Plugin, error) {
	m.mu.Lock()
	defer m.mu.Unlock()

	loader, exists := m.loaders[config.Type]
	if !exists {
		return nil, fmt.Errorf("no loader found for plugin type %s", config.Type)
	}

	plugin, err := loader.Load(ctx, config)
	if err != nil {
		return nil, fmt.Errorf("failed to load plugin: %w", err)
	}

	id := plugin.ID()
	m.plugins[id] = plugin
	m.configs[id] = config
	m.configs[id].Enabled = false

	return plugin, nil
}
